home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / ISAPIEXT.PAK / ISAPIEXT.CPP next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  13.2 KB  |  543 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1997 by Borland International, All Rights Reserved
  4. // written by Michael Sawczyn
  5. //----------------------------------------------------------------------------
  6. #include "IsapiExt.h"
  7. #include <stdio.h>
  8. #include <except.h>
  9.  
  10. TCriticalSection TIsapiExtension::cs;
  11. uint TIsapiStreambuf::bufsize = 1000;
  12. TIsapiExtension *TIsapiExtension::gInstance = NULL;
  13.  
  14. /////////////////////////////////////////////////////////////////////
  15. //    C interface functions
  16. /////////////////////////////////////////////////////////////////////
  17.  
  18. BOOL WINAPI _export GetExtensionVersion(HSE_VERSION_INFO* pVer)
  19. {
  20.    pVer->dwExtensionVersion = MAKELONG(HSE_VERSION_MINOR,
  21.                                        HSE_VERSION_MAJOR);
  22.    if (TIsapiExtension::GetIsapiInstance())
  23.    {
  24.       lstrcpyn(pVer->lpszExtensionDesc,
  25.                TIsapiExtension::GetIsapiInstance()->GetAppName(),
  26.                HSE_MAX_EXT_DLL_NAME_LEN);
  27.    }
  28.    else
  29.    {
  30.       lstrcpyn(pVer->lpszExtensionDesc,
  31.                "IIS Extension",
  32.                HSE_MAX_EXT_DLL_NAME_LEN);
  33.    }
  34.  
  35.    return TRUE;
  36. }
  37.  
  38. DWORD WINAPI _export HttpExtensionProc(EXTENSION_CONTROL_BLOCK* pECB)
  39. {
  40.    TCriticalSection::Lock lock(TIsapiExtension::cs);
  41.    DWORD   retval = HSE_STATUS_ERROR;
  42.  
  43.    if (TIsapiExtension::GetIsapiInstance())
  44.    {
  45.       TIsapiExtension::GetIsapiInstance()->SetControlBlock(pECB);
  46.       TIsapiExtension::GetIsapiInstance()->SetLogInfo("");
  47.  
  48.       if (TIsapiExtension::GetIsapiInstance()->SendHeader())
  49.       {
  50.          pECB->dwHttpStatusCode = retval =
  51.             TIsapiExtension::GetIsapiInstance()->Run();
  52.  
  53.          TIsapiExtension::GetIsapiInstance()->SendFooter();
  54.          TIsapiExtension::GetIsapiInstance()->flush();
  55.          lstrcpy(pECB->lpszLogData,
  56.                  TIsapiExtension::GetIsapiInstance()->GetLogInfo());
  57.          TIsapiExtension::GetIsapiInstance()->SetControlBlock(NULL);
  58.       }
  59.    }
  60.  
  61.    return retval;
  62. }
  63.  
  64. BOOL WINAPI _export TerminateExtension(DWORD dwFlags)
  65. {
  66.    BOOL retval = TRUE;
  67.  
  68.    switch (dwFlags)
  69.    {
  70.       case HSE_TERM_ADVISORY_UNLOAD:
  71.          if (TIsapiExtension::GetIsapiInstance())
  72.          {
  73.             if (TIsapiExtension::GetIsapiInstance()->CanUnload())
  74.                TIsapiExtension::GetIsapiInstance()->Cleanup();
  75.             else
  76.                retval = FALSE;
  77.          }
  78.          break;
  79.  
  80.       case HSE_TERM_MUST_UNLOAD:
  81.          if (TIsapiExtension::GetIsapiInstance())
  82.             TIsapiExtension::GetIsapiInstance()->Cleanup();
  83.    }
  84.  
  85.    return retval;
  86. }
  87.  
  88. /////////////////////////////////////////////////////////////////////
  89. //    TIsapiStreambuf
  90. /////////////////////////////////////////////////////////////////////
  91.  
  92. TIsapiStreambuf::TIsapiStreambuf(TIsapiExtension* aParent)
  93. {
  94.    Parent = aParent;
  95.  
  96.    isapibuf = new char[bufsize];
  97.    memset(isapibuf, 0, bufsize);
  98.    setbuf(isapibuf, bufsize-1, 1);
  99.    setp(isapibuf, isapibuf + (bufsize-1));
  100. }
  101.  
  102. TIsapiStreambuf::~TIsapiStreambuf()
  103. {
  104.  
  105. }
  106.  
  107. /////////////////////////////////////////////////////////////////////
  108. //    TIsapiStream
  109. /////////////////////////////////////////////////////////////////////
  110.  
  111. TIsapiStream::TIsapiStream(TIsapiExtension* parent)
  112. {
  113.    bp = new TIsapiStreambuf(parent);
  114.    ios::init(bp);
  115. }
  116.  
  117. TIsapiStream::~TIsapiStream()
  118. {
  119.    sync();
  120.    delete  bp;
  121.    bp = NULL;
  122. }
  123.  
  124. /////////////////////////////////////////////////////////////////////
  125. //    TIsapiExtension
  126. /////////////////////////////////////////////////////////////////////
  127.  
  128. TIsapiExtension::TIsapiExtension(const char *modulename)
  129.  : browser(*new TIsapiStream(this))
  130. {
  131.    if (gInstance)
  132.       throw xmsg("Can't have more than one TIsapiExtension object active at a time");
  133.  
  134.    name = modulename;
  135.    ecb = NULL;
  136.    data = NULL;
  137.    if (!name.length())
  138.       name = "IIS Extension";
  139.    gInstance = this;
  140.    DefaultHeader = false;
  141.  
  142.    browser.SetParent(this);
  143. }
  144.  
  145. TIsapiExtension::~TIsapiExtension()
  146. {
  147.    gInstance = NULL;
  148.    delete &browser;
  149. }
  150.  
  151. DWORD   TIsapiExtension::Run()
  152. {
  153.    return Success;
  154. }
  155.  
  156. void    TIsapiExtension::SetControlBlock(EXTENSION_CONTROL_BLOCK* lpEcb)
  157. {
  158.    ecb = lpEcb;
  159.    FormVariables.erase(FormVariables.begin(), FormVariables.end());
  160.  
  161.    if (ecb)
  162.    {
  163.       char    buffer[100];
  164.       DWORD   bufferlen = 100;
  165.       ecb->GetServerVariable(ecb->ConnID,
  166.                              "REQUEST_METHOD",
  167.                              (void *) (buffer),
  168.                              &bufferlen);
  169.  
  170.       if (string(buffer) == "GET")
  171.          GetFVsFromString(NULL);
  172.  
  173.       if (string(buffer) == "POST" ||
  174.           (ecb->cbAvailable &&
  175.            string(ecb->lpszContentType) == "application/x-www-form-urlencoded"))
  176.          GetFVsFromStream();
  177.    }
  178.  
  179. }
  180.  
  181. void    TIsapiExtension::GetFVsFromString(const char *s)
  182. {
  183.    if (s == NULL)
  184.       s = GetQueryString();
  185.  
  186.    if (!ecb || !s) return;
  187.  
  188.    while (isspace(*s) || *s == '&')
  189.       s++;                            /* some cases that shouldn't happen */
  190.  
  191.    if (*s != '\0')
  192.    {
  193.       string  name,
  194.               value;
  195.  
  196.       /* get form field name */
  197.       for (int i = 0; *s && *s != '&' && *s != '='; s++, i++)
  198.       {
  199.  
  200.          switch (*s)
  201.          {
  202.             case '+':
  203.                name += ' ';
  204.                break;
  205.             case '%':
  206.                name += dd2c(s[1], s[2]);
  207.                s += 2;
  208.                break;
  209.             default:
  210.                name += *s;
  211.          }
  212.  
  213.       }
  214.  
  215.       switch (*s++)
  216.       {
  217.          case '&':
  218.             break;
  219.          case '=':
  220.             for (int i = 0; *s && *s != '&'; s++, i++)
  221.             {
  222.                switch (*s)
  223.                {
  224.                   case '+':
  225.                      value += ' ';
  226.                      break;
  227.                   case '%':
  228.                      value += dd2c(s[1], s[2]);
  229.                      s += 2;
  230.                      break;
  231.                   default:
  232.                      value += *s;
  233.                }
  234.  
  235.             }
  236.       }
  237.  
  238.       FormVariables.insert(FormVariables.end(),
  239.                            TFormVariable(name, value));
  240.  
  241.       if (*s++ == '&')
  242.          GetFVsFromString(s);
  243.    }
  244.  
  245. }
  246.  
  247. void TIsapiExtension::GetFVsFromStream()
  248. {
  249.    if (!ecb) return;
  250.  
  251.    char *buffer = NULL;
  252.    GetData(&buffer);
  253.  
  254.    if (buffer)
  255.    {
  256.       GetFVsFromString(buffer);
  257.       delete[] buffer;
  258.    }
  259.  
  260. }
  261.  
  262.  
  263. unsigned char TIsapiExtension::dd2c(char d1, char d2)
  264. {
  265.    unsigned char digit;
  266.  
  267.    digit = (d1 >= 'A' ? ((d1 & 0xdf) - 'A') + 10 : (d1 - '0'));
  268.    digit *= 16;
  269.    digit += (d2 >= 'A' ? ((d2 & 0xdf) - 'A') + 10 : (d2 - '0'));
  270.    return digit;
  271. }
  272.  
  273. bool TIsapiExtension::GetVariable(const char *varName, char *buffer, DWORD bufferlen)
  274. {
  275.    DWORD length = bufferlen;
  276.  
  277.    if (ecb && buffer && varName && bufferlen)
  278.    {
  279.       memset(buffer, 0, bufferlen);
  280.  
  281.       if (ecb->GetServerVariable(ecb->ConnID,
  282.                                  const_cast < char *>(varName),
  283.                                  buffer,
  284.                                  &length))
  285.          return true;
  286.  
  287.       for (int l = 0; l < FormVariables.size(); l++)
  288.       {
  289.          if (FormVariables[l].Name == varName)
  290.          {
  291.             lstrcpyn(buffer, FormVariables[l].Value.c_str(), bufferlen);
  292.             buffer[bufferlen - 1] = 0;
  293.             return true;
  294.          }
  295.       }
  296.    }
  297.  
  298.    if (buffer)
  299.       buffer[0] = 0;
  300.    return false;
  301. }
  302.  
  303. string TIsapiExtension::GetVariable(const char *varName)
  304. {
  305.    char buffer[1024];
  306.    DWORD bufferlen = 1024;
  307.  
  308.    if (ecb && varName)
  309.    {
  310.       if (ecb->GetServerVariable(ecb->ConnID,
  311.                                  const_cast < char *>(varName),
  312.                                  (void *) (buffer),
  313.                                  &bufferlen))
  314.          return string(buffer);
  315.  
  316.       for (int l = 0; l < FormVariables.size(); l++)
  317.       {
  318.          if (FormVariables[l].Name == varName)
  319.          {
  320.             lstrcpyn(buffer, FormVariables[l].Value.c_str(), 1024);
  321.             buffer[1023] = 0;
  322.             return string(buffer);
  323.          }
  324.       }
  325.  
  326.    }
  327.  
  328.    return string("");
  329. }
  330.  
  331. void TIsapiExtension::Cleanup()
  332. {
  333.  
  334. }
  335.  
  336. bool TIsapiExtension::CanUnload()
  337. {
  338.    return true;
  339. }
  340.  
  341. void TIsapiExtension::SetLogInfo(const char *info)
  342. {
  343.    lstrcpyn(LogInfo, info, HSE_LOG_BUFFER_LEN);
  344.    LogInfo[HSE_LOG_BUFFER_LEN - 1] = NULL;
  345. }
  346.  
  347. bool TIsapiExtension::GetData(char **data)
  348. {
  349.    bool retval = false;
  350.    *data = 0;
  351.  
  352.    if (ecb)
  353.    {
  354.       *data = new char[ecb->cbTotalBytes];
  355.       memcpy(*data, ecb->lpbData, ecb->cbAvailable);
  356.  
  357.       if (ecb->cbAvailable != ecb->cbTotalBytes)
  358.       {
  359.          DWORD bufsize = 10000;
  360.          char *buffer = new char[bufsize];
  361.          int   offset = ecb->cbAvailable;
  362.  
  363.          while (bufsize)
  364.          {
  365.             ecb->ReadClient(ecb->ConnID,
  366.                             (void *) (buffer),
  367.                             &bufsize);
  368.  
  369.             if (bufsize)
  370.                memcpy(&((*data)[offset]), buffer, bufsize);
  371.             offset += bufsize;
  372.          }
  373.  
  374.          delete[] buffer;
  375.       }
  376.  
  377.       retval = true;
  378.    }
  379.  
  380.    return retval;
  381. }
  382.  
  383. void TIsapiExtension::SendFooter()
  384. {
  385.    if (DefaultHeader)
  386.       browser << "</HTML>";
  387. }
  388.  
  389. bool TIsapiExtension::SendHeader(const char *tags)
  390. {
  391.    if (ecb)
  392.    {
  393.       DWORD   size = 0;
  394.       BOOL    retval = ecb->ServerSupportFunction(ecb->ConnID,
  395.                                                   HSE_REQ_SEND_RESPONSE_HEADER,
  396.                                                   (void *) tags,
  397.                                                   &size,
  398.                                                   NULL);
  399.       if (retval && (!tags || tags[0] == 0))
  400.       {
  401.          browser << "<HTML>";
  402.          DefaultHeader = true;
  403.       }
  404.  
  405.       return retval;
  406.    }
  407.  
  408.    return false;
  409. }
  410.  
  411. bool TIsapiExtension::SendFromURL(const char *url)
  412. {
  413.    if (url && ecb)
  414.    {
  415.       DWORD   size = strlen(url);
  416.       return ecb->ServerSupportFunction(ecb->ConnID,
  417.                                         HSE_REQ_SEND_URL,
  418.                                         (void *) (url),
  419.                                         &size,
  420.                                         NULL);
  421.    }
  422.  
  423.    return false;
  424. }
  425.  
  426. bool TIsapiExtension::GetPhysicalPath(const char *url, char *path, int pathsize)
  427. {
  428.    if (url && path && pathsize && ecb)
  429.    {
  430.       DWORD   size = max(strlen(url), (unsigned int) pathsize) + 1;
  431.       char   *buffer = new char[size];
  432.       lstrcpy(buffer, url);
  433.  
  434.       BOOL    retval = ecb->ServerSupportFunction(ecb->ConnID,
  435.                                                   HSE_REQ_MAP_URL_TO_PATH,
  436.                                                   (void *) (buffer),
  437.                                                   &size,
  438.                                                   NULL);
  439.  
  440.       lstrcpyn(path, buffer, pathsize);
  441.       path[pathsize - 1] = NULL;
  442.       delete[] buffer;
  443.       return retval;
  444.    }
  445.  
  446.    return false;
  447. }
  448.  
  449. bool TIsapiExtension::RedirectToURL(const char *url)
  450. {
  451.    if (url && ecb)
  452.    {
  453.       DWORD   size = strlen(url);
  454.       return ecb->ServerSupportFunction(ecb->ConnID,
  455.                                         HSE_REQ_SEND_URL_REDIRECT_RESP,
  456.                                         (void *) (url),
  457.                                         &size,
  458.                                         NULL);
  459.    }
  460.  
  461.    return false;
  462. }
  463.  
  464. /////////////////////////////////////////////////////////////////////
  465. //    TIsapiStreambuf
  466. /////////////////////////////////////////////////////////////////////
  467.  
  468. int     TIsapiStreambuf::sync()
  469. {
  470.    DWORD   size = strlen(isapibuf);
  471.    DWORD   totalsize = size;
  472.  
  473.    if (Parent && Parent->ecb)
  474.    {
  475.       if (!Parent->ecb->WriteClient(Parent->ecb->ConnID,
  476.                                     (void *) (isapibuf),
  477.                                     &size,
  478.                                     HSE_IO_SYNC))
  479.          return EOF;
  480.  
  481.       if (size != totalsize)
  482.       {
  483.          int     offset = size;
  484.          int     remaining = totalsize - size;
  485.  
  486.          while (remaining)
  487.          {
  488.             size = remaining;
  489.  
  490.             if (!Parent->ecb->WriteClient(Parent->ecb->ConnID,
  491.                                           (void *) (&(isapibuf[offset])),
  492.                                           &size,
  493.                                           HSE_IO_SYNC))
  494.                return EOF;
  495.  
  496.             offset += size;
  497.             remaining -= size;
  498.          }
  499.       }
  500.  
  501.    }
  502.    else
  503.       return EOF;
  504.  
  505.    memset(isapibuf, 0, bufsize);
  506.    setp(isapibuf, isapibuf + (bufsize - 1));
  507.    return 0;
  508. }
  509.  
  510. int TIsapiStreambuf::overflow(int c)
  511. {
  512.    sync();
  513.    return sputc(c);
  514. }
  515.  
  516. /////////////////////////////////////////////////////////////////////
  517. //    TFormVariable
  518. /////////////////////////////////////////////////////////////////////
  519.  
  520. TFormVariable::TFormVariable()
  521. {
  522.  
  523. }
  524.  
  525. TFormVariable::TFormVariable(string& name, string& value)
  526. {
  527.    Name = name;
  528.    Value = value;
  529. }
  530.  
  531. TFormVariable::TFormVariable(const TFormVariable& v)
  532. {
  533.    operator = (v);
  534. }
  535.  
  536. TFormVariable& TFormVariable::operator=(const TFormVariable& v)
  537. {
  538.    Name = v.Name;
  539.    Value = v.Value;
  540.    return *this;
  541. }
  542.  
  543.